#include "EventLoop.h"
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>

int createTimerfd(int sec = 30)
{
    int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); // 创建timerfd
    struct itimerspec timeout;                                             // 定时时间的数据结构
    memset(&timeout, 0, sizeof(struct itimerspec));
    timeout.it_value.tv_sec = sec; // 定时时间
    timeout.it_value.tv_nsec = 0;
    timerfd_settime(tfd, 0, &timeout, 0);
    return tfd;
}
EventLoop::EventLoop(bool ismainloop,int timetvl,int timeout)
    : ep_(new Epoll), wakeupfd_(eventfd(0, EFD_NONBLOCK)),
      wakechannel_(new Channel(this, wakeupfd_)),
      timetvl_(timetvl),timeout_(timeout),
      timerfd_(createTimerfd(timetvl_)), timerchannel_(new Channel(this, timerfd_)), ismainloop_(ismainloop),stop_(false)
{
    // printf("pppppppppppppp");
    // ep_ = new Epoll;
    wakechannel_->setreadcallback(std::bind(&EventLoop::haddlewakeup, this));
    wakechannel_->enablereading();

    timerchannel_->setreadcallback(std::bind(&EventLoop::handletimer, this));
    timerchannel_->enablereading();
}
EventLoop::~EventLoop()
{
    // delete ep_;
}

Epoll *EventLoop::ep()
{
    // return ep_;
    return ep_.get();
}

void EventLoop::run()
{
    threadid_ = syscall(SYS_gettid);
    // printf("EventLoop thread is: %d\n", syscall(SYS_gettid));
    while (!stop_)
    {
        std::vector<Channel *> channels;
        channels = ep_->loop(); // 6秒
        // 如果channels为空，表示超时，回调TcpServer::epolltimeout()
        if (channels.size() == 0)
        {
            epolltimeoutcallback_(this);
        }
        else
        {
            for (auto ch : channels)
            {
                ch->handleevent();
            }
        }
    }
}

// void EventLoop::updatechannel(Channel *ch)
// {
//     struct epoll_event ev;
//     ev.data.ptr = ch;
//     ev.events = ch->events();

//     if(ch->inpoll()){//已经在树上就更新
//         if(epoll_ctl(ep()->epollfd(),EPOLL_CTL_MOD,ch->fd(),&ev)==-1){
//             perror("epoll_ctl error");
//             exit(-1);
//         }
//     }else{// 添加
//         if(epoll_ctl(epollfd_,EPOLL_CTL_ADD,ch->fd(),&ev)==-1){
//             perror("epoll_ctl error");
//             exit(-1);
//         }
//         ch->setinepoll();
//     }
// }

void EventLoop::setepolltimeoutcallback(std::function<void(EventLoop *)> f)
{
    epolltimeoutcallback_ = f;
}

void EventLoop::updatechannel(Channel *ch)
{
    // struct epoll_event ev;
    // ev.data.ptr = ch;
    // ev.events = ch->events();

    // if(ch->inpoll()){//已经在树上就更新
    //     if(epoll_ctl(ep_->epollfd(),EPOLL_CTL_MOD,ch->fd(),&ev)==-1){
    //         perror("epoll_ctl error");
    //         exit(-1);
    //     }
    // }else{// 添加
    //     if(epoll_ctl(ep_->epollfd(),EPOLL_CTL_ADD,ch->fd(),&ev)==-1){
    //         perror("epoll_ctl error");
    //         exit(-1);
    //     }
    //     ch->setinepoll();
    // }
    ep_->updatechannel(ch);
}

void EventLoop::removechannel(Channel *ch)
{
    ep_->removechannel(ch);
}

bool EventLoop::isinloopthread()
{
    return threadid_ == syscall(SYS_gettid);
}

void EventLoop::queueinloop(std::function<void()> f)
{
    {
        std::lock_guard<std::mutex> gd(mutex_);
        taskqueue_.push(f);
    }
    // 唤醒事件循环。。。
    wakeup();
}

void EventLoop::wakeup()
{
    uint64_t val = 1;
    write(wakeupfd_, &val, sizeof(val));
}

void EventLoop::haddlewakeup()
{
    printf("----------------\n");
    uint64_t val;
    read(wakeupfd_, &val, sizeof(val)); // cong eventfd zhong du qu shu ju ,yao bu su shi jian hui yi zhi chu da(shui ping chu fa);
    std::function<void()> fn;
    std::lock_guard<std::mutex> gd(mutex_);
    while (taskqueue_.size() > 0)
    {
        fn = std::move(taskqueue_.front());
        taskqueue_.pop();
        fn();
    }
}

// 闹钟响的时候执行这个函数
void EventLoop::handletimer()
{
    struct itimerspec timeout; // 定时时间的数据结构
    memset(&timeout, 0, sizeof(struct itimerspec));
    timeout.it_value.tv_sec = timetvl_; // 定时时间
    timeout.it_value.tv_nsec = 0;
    timerfd_settime(timerfd_, 0, &timeout, 0);

    if (ismainloop_)
    {
        // printf("主事件循环 thread:%d 闹钟响了\n",syscall(SYS_gettid));
    }
    else
    {
        printf("IO事件循环 thread:%d 闹钟响了:", syscall(SYS_gettid));
        time_t now = time(0);
        // for(auto aa:conns_){
        //     printf("%d ",aa.first);
        //     if(aa.second->timeout(now,10)){
        //         conns_.erase(aa.first);
        //         // removeconncallback_(aa.first);
        //     }
        // }
        for (auto it = conns_.begin(); it != conns_.end();)
        {
            printf("%d ", it->first);
            if (it->second->timeout(now, timeout_))
            {
                removeconncallback_(it->first);
                {
                    std::lock_guard<std::mutex> gd(mmutex_);
                    it = conns_.erase(it); // ✅ 安全删除，返回下一个迭代器
                }
            }
            else
            {
                ++it; // 正常前进
            }
        }

        printf("\n");
    }
}

void EventLoop::newconnection(std::shared_ptr<Connection> conn)
{
    std::lock_guard<std::mutex> gd(mmutex_);
    conns_[conn->fd()] = conn;
}

void EventLoop::setremoveconncallback(std::function<void(int)> f)
{
    removeconncallback_ = f;
}

void EventLoop::stop()
{
    stop_ = true;
    wakeup();//唤醒
}